package pl.edu.pw.elka.dzielins.revanalyzer.model;

public class Arity {
	public static final Arity SET = new Arity(0,true);
	public static final Arity SOME = new Arity(1,true);
	public static final Arity ONE = new Arity(1);
	public static final Arity LONE = new Arity(0,1);
	public static final Arity NONE = new Arity(0);
	
	private float maxArity;
	private float minArity;
	
	public Arity(float minArity, float maxArity) {
		this.maxArity = maxArity;
		this.minArity = minArity;
	}

	public Arity(int arity) {
		this.maxArity = this.minArity = arity;
	}

	public Arity(int minArity, int maxArity) {
		this.maxArity = maxArity;
		this.minArity = minArity;
	}

	public Arity(int minArity, boolean maxArityIsInfinite) {
		this.minArity = minArity;
		this.maxArity = Float.POSITIVE_INFINITY;
	}

	public boolean isVariadic() {
		return (maxArity != minArity);
	}

	public int getArity() {
		if (isVariadic())
			return (int) Float.NaN;
		else
			return (int) minArity;
	}

	public int getMaxArity() {
		return (int) maxArity;
	}

	public int getMinArity() {
		return (int) minArity;
	}

	public boolean isMaxArityInfinite() {
		return (Float.isInfinite(maxArity));
	}

	public boolean check(int n) {
		return (n>=minArity && n<=maxArity);
	}
	
	public Arity union(Arity other) {
		// check if there is intersection
		if (intersection(other)!=null)
			return new Arity(Math.min(this.minArity, other.minArity),Math.max(this.maxArity, other.maxArity));
		return null;
	}
	
	public Arity intersection(Arity other) {
		if (this.minArity<=other.maxArity && this.maxArity >= other.minArity)
			return new Arity(Math.max(this.minArity, other.minArity),Math.min(this.maxArity, other.maxArity));
		else return null;
	}
	
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Arity other = (Arity) obj;
		if (maxArity != other.maxArity)
			return false;
		if (minArity != other.minArity)
			return false;
		return true;
	}

}
